<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript" src="../jsunit/app/jsUnitCore.js"></script>
    <script type="text/javascript" src="../../src/objx.test.js"></script>
    <script type="text/javascript" src="../../src/objx.js"></script>
    <script type="text/javascript">
    
    	function test_pascal(){
    		
    		assertNotUndefined("objx.pascal", objx.pascal);
    		
    		assertEquals("SimonHoward", objx.pascal("simonHoward"));
    		assertEquals("MatRyer", objx.pascal("matRyer"));
    		
    	}
    
        function test_args()
        {
        
            // test the function that pulls arguments out of
            // a function.

            var func = function(one, two, three){};
            var args = objx.args(func);

            assertEquals("Expected an array with three strings.", 3, args.length);
            assertEquals("one", args[0]);
            assertEquals("two", args[1]);
            assertEquals("three", args[2]);
            
            // test that when no arguments are present, we get an empty array back
            args = objx.args(function(){});
            assertEquals(0, args.length);
        
        }
        
        function test_argc()
        {
        
            // test to ensure argc returns the correct number
            // of arguments
        
            var func = function(one, two, three){};
             
            var argc = objx.argc(func);
        
            assertEquals("Expected an array with three strings.", 3, argc);
        
        }
        
        function test_nf()
        {
        
            // ensure 'nf' exists - shortcut for NoFunction
            assertNotUndefined(objx.nf);

        }

        
        function test_ex()
        {
        
            // ex 'extends' one object with the properties of another
            var o1 = {
                oneMethod: function(){ return 1; }
            };
            var o2 = {
                twoMethod: function(){ return 2; }
            }
            var o3 = {
                threeMethod: function(){ return 3; }
            }
            
            objx.ex(o1, o2, o3);
            
            assertNotUndefined(o1.twoMethod);
            assertEquals(o1.twoMethod.toString(), o2.twoMethod.toString());
            assertNotUndefined(o1.threeMethod);
            assertEquals(o1.threeMethod.toString(), o3.threeMethod.toString());
        
        	// ensure the return type of objx.ex is the object being extended
        	assertEquals("The return type of objx.ex is expected to be the object being extended.", o1, objx.ex(o1, o2, o3));
        
        }
        
        function test_ex$(){
        
        	var o = objx.ex$({ 
        		one: function(){}, 
        		two: function(){} 
        	}, {
        		three: function(){},
        		four: function(){}
        	});
        
        	assertNotUndefined(o.one);
        	assertNotUndefined(o.two);
        	assertNotUndefined(o.three);
        	assertNotUndefined(o.four);
        
        }
        
        function test_bind()
        {
        
        	var obj = {
        		
        		value: 123
        		
        	};
        	
        	var myFunc = function(i){
        	
        		assertEquals(123, i);
        	
        		assertEquals(this.value, i);
        	}
        	
        	var contextLoadedFunc = objx.bind(myFunc, obj);
        	
        	contextLoadedFunc(123);
        
        }
        
        function test_bind_args()
        {
        
        	var obj = {
        		val: 1
        	};
        	
        	var obj2 = {
        		val: 2
        	};
        	
        	function myApp(i){
        		return this.val + i;
        	}

        	assertEquals(2, objx.bind(myApp, obj)(1));
        	assertEquals(7, objx.bind(myApp, obj2)(5));

        }
        
        function test_isf()
        {
        
            assertFalse(objx.isf({}));
            assertFalse(objx.isf(123));
            assertFalse(objx.isf("123"));
        
            assertTrue(objx.isf(function(){}));
            
            var f = function(){};
            
            assertTrue(objx.isf(f));
        
        }
        
        function test_isb()
        {
        
        	assertTrue("objx.isb(true)", objx.isb(true));
        	assertTrue("objx.isb(false)", objx.isb(false));
        	
        	var m = true;
        	
        	assertTrue("objx.isb(m)", objx.isb(m));
        	
        	assertFalse("objx.isb(function(){})", objx.isb(function(){}));
        	assertFalse("objx.isb(123)", objx.isb(123));
        
        }
        
        function test_isi()
        {
        
        	assertTrue("Interface({})", objx.isi(Interface({})));
        	
        	var I = Interface({ m: Method() });
        
        	assertTrue("I", objx.isi(I));
        	
        	assertFalse("Class({})", objx.isi(Class({})));
        	assertFalse("null", objx.isi(null));
        	assertFalse("false", objx.isi(false));
        	assertFalse("true", objx.isi(true));
        	assertFalse("123", objx.isi(123));
        
        }
        
        function test_isc()
        {
        
        	assertTrue("Class({})", objx.isc(Class({})));
        	
        	var C = Class({ m: function(){}} );
        
        	assertTrue("C", objx.isc(C));
        	
        	assertFalse("Interface({})", objx.isc(Interface({})));
        	assertFalse("null", objx.isc(null));
        	assertFalse("false", objx.isc(false));
        	assertFalse("true", objx.isc(true));
        	assertFalse("123", objx.isc(123));
        
        }
        
        function test__colargs(){
        
        	var arg1 = {};
        	var arg2 = {};
        	var args = [arg1, arg2];
        
        	var context = {};
        	
        	var actualArgs = objx.__colargs(context, args);
        	
        	assertEquals(context, actualArgs[0]);
        	assertEquals(arg1, actualArgs[1]);
        	assertEquals(arg2, actualArgs[2]);
        
        }
        
        function xtest_complexBindingSituation(){
        
        	function alertContext(contextObject, value, other){
        		alert(contextObject.context + ":" + value + " : " + other);
        	}
        	function passMethod(){
        		alertContext.apply(null, objx.__colargs(this, arguments));
        	}
        
        
        	var objectOne = new (Class({ context: "one" }))();
        	var objectTwo = new (Class({ context: "two" }))();

			objectOne.alertContext = objx.bind(passMethod, objectOne, "alert_one");
			objectTwo.alertContext = objx.bind(passMethod, objectTwo, "alert_two");
			
        	
        	objectOne.alertContext(123);
        	objectTwo.alertContext(456);
        	
        }
            
    </script>
</head>
<body>
</body>
</html>